﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using Xoohoo.Extensions;
using Xoohoo.Models.InputModels;
using Xoohoo.Repositories.SqlServerEF.Entities;
using XM = Xoohoo.Models;
using System.Data.SqlClient;
using System.Linq.Expressions;

namespace Xoohoo.Repositories.SqlServerEF
{
    public class RoleRepository : IRoleRepository
    {
        private readonly XoohooContext _db = new XoohooContext();
        private readonly Expression<Func<Role, XM.Role>> selector;

        public RoleRepository()
        {
            selector = r => new XM.Role
            {
                RoleID = r.RoleID,
                RoleName = r.RoleName,
                IsSystem = r.IsSystem,
                DisplayOrder = r.DisplayOrder,
                Permissions = from p in r.Permissions
                              orderby p.DisplayOrder
                              select new XM.PermissionBasic
                              {
                                  ModuleName = p.ModuleName,
                                  PermissionID = p.PermissionID,
                                  PermissionName = p.PermissionName
                              }
            };
        }

        protected DbSet<Role> DbSet
        {
            get { return _db.Roles; }
        }

        #region IRoleRepository 成员

        public XM.Role GetItem(Guid roleID)
        {
            return DbSet.Select(selector).FirstOrDefault(r => r.RoleID == roleID);
        }

        public XM.Role GetItem(string roleName)
        {
            return DbSet.Select(selector).FirstOrDefault(r => r.RoleName == roleName);
        }

        public List<XM.RoleBasic> GetList()
        {
            return (from r in DbSet
                    orderby r.DisplayOrder
                    select new XM.RoleBasic
                    {
                        RoleID = r.RoleID,
                        RoleName = r.RoleName,
                        IsSystem = r.IsSystem,
                        DisplayOrder = r.DisplayOrder
                    }).ToList();
        }

        public bool Save(RoleInput roleInput)
        {
            Role roleToSave = null;
            if (!roleInput.RoleID.IsNullOrEmpty())
            {
                roleToSave = DbSet.FirstOrDefault(m => m.RoleID == roleInput.RoleID.Value);
                if (roleToSave == null)
                    return false;
            }
            else
            {
                roleToSave = new Role
                {
                    RoleID = Guid.NewGuid()
                     ,
                    IsSystem = false
                };
                DbSet.Add(roleToSave);
                int maxDisplayOrder = DbSet.Max(m => (int?)m.DisplayOrder) ?? 0;
                roleToSave.DisplayOrder = maxDisplayOrder + 1;
            }
            roleToSave.RoleName = roleInput.RoleName;
            //移除全部
            //if (!roleToSave.Permissions.IsNullOrEmpty())
            //{
            //    for (int i = 0; i < roleToSave.Permissions.Count;i++ )
            //        roleToSave.Permissions.Remove(roleToSave.Permissions.ElementAt(0));
            //}
            //添加项
            //if (!role.Permissions.IsNullOrEmpty())
            //{
            //    roleToSave.Permissions = (from p in _db.Permissions
            //                              where role.Permissions.Contains(p.PermissionID)
            //                              select p).ToList();
            //}
            //移除项
            if (!roleToSave.Permissions.IsNullOrEmpty())
            {
                if (!roleInput.Permissions.IsNullOrEmpty())
                {
                    List<Permission> permissionToRemove = (from p in roleToSave.Permissions
                                          where !roleInput.Permissions.Contains(p.PermissionID)
                                          select p).ToList();
                    for (int i = 0; i < permissionToRemove.Count; i++)
                        roleToSave.Permissions.Remove(permissionToRemove[i]);
                }
                else
                {
                    roleToSave.Permissions.Clear();
                }
            }
            //添加项
            if (!roleInput.Permissions.IsNullOrEmpty())
            {
                //要添加的ID集
                List<Guid> permissionIDToAdd = (from p in roleInput.Permissions
                                                where !roleToSave.Permissions.Any(m => m.PermissionID == p)
                                                select p).ToList();

                //要添加的项
                List<Permission> permissionToAdd = (from p in _db.Permissions
                                                    where permissionIDToAdd.Contains(p.PermissionID)
                                                    select p).ToList();
                foreach (var item in permissionToAdd)
                    roleToSave.Permissions.Add(item);

            }
            _db.SaveChanges();
            return true;
        }

        public bool Remove(Guid roleID)
        {
            Role roleToRemove = DbSet.FirstOrDefault(m => m.RoleID == roleID);
            if (roleToRemove == null||roleToRemove.IsSystem) return false;

            string sql;

            sql = "Update Role Set DisplayOrder=DisplayOrder-1 Where DisplayOrder>@DisplayOrder";
            _db.Database.ExecuteSqlCommand(sql, new SqlParameter("DisplayOrder", roleToRemove.DisplayOrder));

            sql = "Delete RolePermissionRelationShip Where RoleID=@RoleID";
            _db.Database.ExecuteSqlCommand(sql, new SqlParameter("RoleID", roleID));

            sql = "Delete UserGroupRoleRelationShip Where RoleID=@RoleID";
            _db.Database.ExecuteSqlCommand(sql, new SqlParameter("RoleID", roleID));

            DbSet.Remove(roleToRemove);

            _db.SaveChanges();

            return true;
        }

        public bool Move(Guid roleID, XM.MovingTarget target)
        {
            var roleToMove = DbSet.FirstOrDefault(m => m.RoleID == roleID);

            // 保证DisplayOrder为 1 的“系统管理员”不被移动
            if (roleToMove == null || roleToMove.DisplayOrder == 1) return false;

            //防止DisplayOrder为2的项非法篡改"系统管理员",也就是说DisplayOrder必须大于2
            if (XM.MovingTarget.Up == target)
            {
                if (roleToMove.DisplayOrder < 3) return false;

                var targetRole = DbSet.OrderByDescending(m=>m.DisplayOrder).FirstOrDefault(m => m.DisplayOrder < roleToMove.DisplayOrder);
                //某种原因导致当前项之前已经没有项了
                if (targetRole == null) return false;

                roleToMove.DisplayOrder--;
                targetRole.DisplayOrder++;
                _db.SaveChanges();

            }
            else if (XM.MovingTarget.Down == target)
            {
                var targetRole = DbSet.OrderBy(m => m.DisplayOrder).FirstOrDefault(m => m.DisplayOrder > roleToMove.DisplayOrder);
                //某种原因导致当前项之后已经没有项了
                if (targetRole == null) return false;

                roleToMove.DisplayOrder++;
                targetRole.DisplayOrder--;
                _db.SaveChanges();
            }
            return true;
        }

        #endregion

        #region IDisposable Members

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    _db.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        #endregion

        #region Private Methods


        #endregion
    }
}
